package kpi.java_training.utils;

import org.w3c.dom.*;
import org.xml.sax.SAXException;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;

import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;

/**
 * @author Alexander Palleev
 * @author palleev@ukr.net
 */
public class Log {

    private final static String LOG_NAME = "testing_log.xml";

    public Log() {
        createLogFile();
    }

    private void createLogFile() {
        File temporaryFile = new File(LOG_NAME);

        if (!temporaryFile.exists()) {
            try {
                DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
                DocumentBuilder docBuilder = docFactory.newDocumentBuilder();

                // root elements
                Document document = docBuilder.newDocument();
                document.setXmlStandalone(true);
                Element rootElement = document.createElement("errors");
                rootElement.normalize();
                document.appendChild(rootElement);

                // write the content into xml file
                TransformerFactory transformerFactory = TransformerFactory.newInstance();
                Transformer transformer = transformerFactory.newTransformer();
                DOMSource source = new DOMSource(document);
                StreamResult streamResult = new StreamResult(new File(LOG_NAME));

                transformer.transform(source, streamResult);

            } catch (ParserConfigurationException pce) {
                pce.printStackTrace();
            } catch (TransformerException tfe) {
                tfe.printStackTrace();
            }
        }
    }

    public static void writeToLog(Exception e) {
        String className = e.getStackTrace()[4].getClassName();
        String methodName = e.getStackTrace()[4].getMethodName();
        int lineNumber = e.getStackTrace()[4].getLineNumber();

        try {
            DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
            DocumentBuilder docBuilder = docFactory.newDocumentBuilder();
            Document document = docBuilder.parse(LOG_NAME);

            // define root elements
            Element rootElement = document.getDocumentElement();
            rootElement.normalize();

            // define error elements
            Element errorElement = document.createElement("error");
            rootElement.appendChild(errorElement);

            // date element
            Element dateElement = document.createElement("date");
            Date currentDate = new Date();
            SimpleDateFormat dateFormat = new SimpleDateFormat("dd.MM.yyyy hh:mm");
            dateElement.appendChild(document.createTextNode(dateFormat.format(currentDate)));
            errorElement.appendChild(dateElement);

            // class name element
            Element classElement = document.createElement("class");
            classElement.appendChild(document.createTextNode(className));
            errorElement.appendChild(classElement);

            // method name element
            Element methodElement = document.createElement("method");
            methodElement.appendChild(document.createTextNode(methodName));
            errorElement.appendChild(methodElement);

            // line number element
            Element lineElement = document.createElement("line");
            lineElement.appendChild(document.createTextNode(Integer.toString(lineNumber)));
            errorElement.appendChild(lineElement);

            // message
            Element messageElement = document.createElement("message");
            lineElement.appendChild(document.createTextNode(e.getMessage()));
            errorElement.appendChild(messageElement);

            // creating and writing to xml file
            TransformerFactory transformerFactory = TransformerFactory.newInstance();
            Transformer transformer = transformerFactory.newTransformer();
            DOMSource domSource = new DOMSource(document);
            StreamResult streamResult = new StreamResult(new File(LOG_NAME).getAbsolutePath());

            transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "2");
            transformer.setOutputProperty(OutputKeys.INDENT, "yes");
            transformer.transform(domSource, streamResult);

        } catch (ParserConfigurationException pce) {
            pce.printStackTrace();
        } catch (TransformerException tfe) {
            tfe.printStackTrace();
        } catch (IOException ioe) {
            ioe.printStackTrace();
        } catch (SAXException sae) {
            sae.printStackTrace();
        }
    }

}

